<template>
	<div style="width: 100%; height: 100%">
		<Toolbar
			v-if="initFlag"
			v-show="!props.toolbarConfig || props.toolbarConfig.viewFlag"
			:config="props?.toolbarConfig"
			:lf="lf"
		></Toolbar>
		<div class="processContainer" ref="container"></div>
		<NodeHover
			v-if="initFlag"
			:config="nodeHoverConfig"
			:componentsViewConfig="props?.componentsViewConfig"
			:lf="lf"
		></NodeHover>
		<EdgeHover v-if="initFlag" :config="edgeHoverConfig" :lf="lf"></EdgeHover>
		<NodeProperties v-if="initFlag" :lf="lf" :config="nodePropertiesConfig"></NodeProperties>

		<Components
			v-if="initFlag"
			v-show="!props.componentsViewConfig || props.componentsViewConfig?.viewFlag"
			:lf="lf"
			:config="props?.componentsViewConfig"
		></Components>

		<FloatToolbar
			v-if="initFlag"
			v-show="!props.floatToolbarViewConfig || props.floatToolbarViewConfig?.viewFlag"
			:lf="lf"
			:config="props?.floatToolbarViewConfig"
		></FloatToolbar>
	</div>
</template>

<script setup>
	import LogicFlow from '@logicflow/core'
	import '@logicflow/core/lib/style/index.css'
	import {
		Control,
		Group,
		InsertNodeInPolyline,
		Menu,
		MiniMap,
		SelectionSelect,
		Snapshot,
		DynamicGroup
	} from '@logicflow/extension'
	import '@logicflow/extension/lib/style/index.css'
	import { registerEvent } from './event.js'
	import { getData } from './mockData.js'
	import { registerCustomNode } from './node/register.js'
	import { registerCustomEdge } from './edge/register.js'
	import { defineExpose } from 'vue'

	import { registerTheme } from './theme.js'
	import { registerPlugin } from './plugin.js'
	import { config } from './config.js'
	import NodeHover from './node/nodeHover.vue'
	import EdgeHover from './edge/edgeHover.vue'

	import { customMountFunc } from './functions.js'
	import NodeProperties from './node/nodeProperties.vue'
	import Components from './components.vue'
	import Toolbar from './toolbar.vue'
	import FloatToolbar from './floatToolbar.vue'
	import $bus from '@/utils/mitt.js'
	import { nanoid } from 'nanoid'

	// import { getKeyboard } from "./keybard.js";

	const props = defineProps([
		'toolbarConfig',
		'id',
		'name',
		'type', //workflow or process
		'componentsViewConfig',
		'floatToolbarViewConfig',
		'nodePropertiesConfig',
		'childFlowFlag',
		'initCallBack',
		'pluginConfig',
		'file'
	])

	// 全局使用 每一个lf实例都具备 Control
	const container = ref()

	const key = ref()

	const nodeHoverConfig = ref({
		showFlag: false
	})

	const edgeHoverConfig = ref({
		showFlag: false
	})

	const { proxy } = getCurrentInstance()

	const nodePropertiesConfig = ref({
		showFlag: false
	})

	onMounted(() => {
		if (!props.type) {
			props.type = 'process'
		}
		initEngine()
	})

	let initFlag = ref(false)
	let lf = null

	const initEngine = async () => {
		//获取数据
		//实例化
		lf = new LogicFlow({
			container: container.value,
			...config,
			// 移动已有边时会有 currentEdge 信息, 否则为空
			edgeGenerator: (sourceNode, targetNode, currentEdge) => {
				// 起始节点类型 rect 时使用 自定义的边 custom-edge
				//if (sourceNode.type === 'rect') return 'custom-edge'
				const edgeCode = lf.getNodeOutEdgeCode(sourceNode.id)
				return edgeCode || 'common-line'
			},
			//只能这样配置
			keyboard: {
				enabled: true,
				shortcuts: [
					{
						keys: ['cmd'],
						callback: (e) => {
							lf.openSelectionSelect()
						},
						action: ['keydown']
					},

					{
						keys: ['cmd'],
						callback: (e) => {
							lf.closeSelectionSelect()
						},
						action: ['keyup']
					},
					{
						keys: ['backspace'],
						callback: (e) => {},
						action: ['keydown']
					}
				]
			},

			plugins: [Control, Group, InsertNodeInPolyline, MiniMap, Menu, SelectionSelect, Snapshot, DynamicGroup]
		})

		setChildFlowFlag(lf)

		//设置ID
		setId(lf)

		//设置名称
		setName(lf)

		mountFunc(lf)

		//皮肤配置
		registerTheme(lf)

		//注册自定义node
		registerCustomNode(lf)

		//注册自定义连线
		registerCustomEdge(lf)

		//插件配置
		registerPlugin(lf, props.pluginConfig)

		//注册事件
		registerEvent(lf)

		//渲染数据
		await lf.renderFile(props.file)

		if (props.initCallBack) {
			props.initCallBack()
		}
		initFlag.value = true
	}

	const setChildFlowFlag = (lf) => {
		lf.childFlowFlag = props.childFlowFlag || false
	}
	const setId = (lf) => {
		if (props.file) {
			return
		}
		if (props.id) {
			lf.id = props.id
		} else {
			lf.id = proxy.$route?.query?.id
		}

		key.value = lf.id
	}
	const setName = (lf) => {
		if (props.name) {
			lf.processName = props.name
		}
	}
	const mountFunc = (lf) => {
		//把悬浮配置到引擎配置上面
		lf.setNodeHoverConfig = setNodeHoverConfig
		lf.setNodePropertiesConfig = setNodePropertiesConfig
		lf.setEdgeHoverConfig = setEdgeHoverConfig
		customMountFunc(lf)
	}

	const setEdgeHoverConfig = (config) => {
		edgeHoverConfig.value = { ...config }
	}

	const setNodeHoverConfig = (config) => {
		nodeHoverConfig.value = { ...config }
	}
	const setNodePropertiesConfig = (config) => {
		nodePropertiesConfig.value = { ...config }
	}
	const batchLogAndStepStatusFormat = (data) => {
		if (!data || data.length <= 0) {
			return
		}
		lf.clearBuffs()
		for (let dt of data) {
			logAndStepStatusFormat(dt)
		}
	}
	const logAndStepStatusFormat = (dt) => {
		lf.logAndStepStatusFormat({
			data: dt,
			type: 'log'
		})
	}
	defineExpose({
		batchLogAndStepStatusFormat,
		logAndStepStatusFormat
	})

	$bus.on('processReloadJsonEvent', (car) => {
		lf.renderFile(car)
	})
</script>

<style scoped>
	.processContainer {
		width: 100%;
		height: 100%;
	}
</style>
